package bsk_dac;

import bsk_dac.accesscontrol.AccessType;
import bsk_dac.accesscontrol.TableAccess;
import bsk_dac.accesscontrol.UserAccess;
import bsk_dac.database.DatabaseFacade;
import bsk_dac.tables.TablesManager;
import bsk_dac.users.IUsersManager;
import bsk_dac.users.User;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JToggleButton;

/**
 * Klasa reprezentuje elementy pierwszej kolumny. Jest to panel z rozciągniętym toggle buttonem z nazwą użytkownika.
 */
public class UserPanel extends javax.swing.JPanel {

    private User user;
    private DACPanel dacPanel;
    private IUsersManager usersManager;


    /** Creates new form UserPanel */
    public UserPanel(DACPanel dacPanel) {
        initComponents();
        this.dacPanel = dacPanel;
        
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        userToggleBtn = new javax.swing.JToggleButton();
        jButton1 = new javax.swing.JButton();

        setBackground(new java.awt.Color(217, 217, 217));
        setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        setMaximumSize(new java.awt.Dimension(200, 32767));
        setMinimumSize(new java.awt.Dimension(200, 87));
        setPreferredSize(new java.awt.Dimension(200, 87));
        setLayout(new java.awt.BorderLayout());

        userToggleBtn.setFont(new java.awt.Font("DejaVu Sans", 0, 24));
        userToggleBtn.setText("jToggleButton1");
        userToggleBtn.setMaximumSize(new java.awt.Dimension(200, 27));
        userToggleBtn.setMinimumSize(new java.awt.Dimension(200, 27));
        userToggleBtn.setPreferredSize(new java.awt.Dimension(200, 27));
        userToggleBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                userToggleBtnActionPerformed(evt);
            }
        });
        add(userToggleBtn, java.awt.BorderLayout.CENTER);

        jButton1.setText("Oddaj uprawnienia");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        add(jButton1, java.awt.BorderLayout.PAGE_END);
    }// </editor-fold>//GEN-END:initComponents

    private void userToggleBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_userToggleBtnActionPerformed
    }//GEN-LAST:event_userToggleBtnActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        givePermissions();
}//GEN-LAST:event_jButton1ActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JToggleButton userToggleBtn;
    // End of variables declaration//GEN-END:variables

    public void addActionListenerToToggleBtn(ActionListener actionListener) {
        userToggleBtn.addActionListener(actionListener);
    }

    public void setUser(User user) {
        this.user = user;
        if (user.getUserAccess().getPrivilegesStatus(AccessType.GIVE_PRIV) == false) {
            //  jButton1.setVisible(false);
        }
        jButton1.setVisible(false);
    }

    public void removeAllPermissions(){
        usersManager = MainDACFrame.getUsersManager();
          try {

            ArrayList<String> tables = TablesManager.getTableManager().getAvaiableTables();
            ArrayList<Integer> historyId = new ArrayList<Integer>();
            //Użytkownik który dostanie uprawnienia
            int geter_id = DatabaseFacade.getUserId(user.getUserName());
            int table_id = 0;

            for (String tableName : tables) {
                table_id = DatabaseFacade.getTableId(tableName);
                revokePermission(table_id, "select", tableName, geter_id);
                revokePermission(table_id, "insert", tableName, geter_id);
                revokePermission(table_id, "delete", tableName, geter_id);
                revokePermission(table_id, "update", tableName, geter_id);

                //Usunięcua histori dla danego użytkownika
                historyId = DatabaseFacade.getHistoryIDByUserGet(geter_id, "select",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(geter_id, "insert",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(geter_id, "delete",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(geter_id, "update",table_id);
                DatabaseFacade.deleteHistories(historyId);



            }
            dacPanel.refreshPanelsAccess();

        } catch (SQLException ex) {
            Logger.getLogger(UserPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void givePermissions() {
        usersManager = MainDACFrame.getUsersManager();
        try {
            if(MainDACFrame.isAdmin == true){
                DatabaseFacade.setAdmin(user.getUserName());
                MainDACFrame.isAdmin = false;
                dacPanel.mainDACFrame.loadPrivilegesPanel();
            }

            //Przekazanie wszystkich uprawnień dla tego użytkownika
            User selectedUser = MainDACFrame.getUsersManager().getSelectedUser();
            ArrayList<String> tables = TablesManager.getTableManager().getAvaiableTables();
            ArrayList<Integer> historyId = new ArrayList<Integer>();
            //Użytkownik który daje swoje uprawnienia
            int giver_id = DatabaseFacade.getUserId(selectedUser.getUserName());
            //Użytkownik który dostanie uprawnienia
            int geter_id = DatabaseFacade.getUserId(user.getUserName());
            int table_id = 0;
            int tp_id = 0;
            for (String tableName : tables) {
                table_id = DatabaseFacade.getTableId(tableName);
                TableAccess access = selectedUser.getTableAccess(tableName);

                DatabaseFacade.setTablePriveleges(giver_id, table_id, "select", false, false);
                DatabaseFacade.setTablePriveleges(giver_id, table_id, "insert", false, false);
                DatabaseFacade.setTablePriveleges(giver_id, table_id, "delete", false, false);
                DatabaseFacade.setTablePriveleges(giver_id, table_id, "update", false, false);
                TableAccess changedAccess = user.getTableAccess(tableName);
                boolean givePermission = false;

                //SELECT
                if (access.getPrivilegesStatus(AccessType.SELECT)) {
                    if(changedAccess.getPrivilegesStatus(AccessType.SELECT) == false){
                        //UPDATE histori
                        tp_id = DatabaseFacade.getTablePrivelegesId(geter_id, table_id, "select");
                        DatabaseFacade.updateHistoryID(giver_id, geter_id, "select", table_id, tp_id);

                    }

                    changedAccess.setPrivileges(AccessType.SELECT, true);

                    if (access.getUserGivePermission(AccessType.SELECT)) {
                        changedAccess.setUserGivePermission(AccessType.SELECT, true);
                        givePermission = true;
                    } else {
                        givePermission = changedAccess.getUserGivePermission(AccessType.SELECT);
                    }

                    if (DatabaseFacade.isPermissionsInDatabase(geter_id, table_id, "select")) {
                        DatabaseFacade.setTablePriveleges(geter_id, table_id, "select", true, givePermission);
                    } else {
                        DatabaseFacade.insertNewPermission(geter_id, table_id, "select", true, givePermission);
                    }

                    //Zrobienie revoka dla selecta
                    revokePermission(table_id, "select", tableName, giver_id);
                }

                //INSERT
                if (access.getPrivilegesStatus(AccessType.INSERT)) {
                    if(changedAccess.getPrivilegesStatus(AccessType.INSERT)== false){
                        //UPDATE histori
                        tp_id = DatabaseFacade.getTablePrivelegesId(geter_id, table_id, "insert");
                        DatabaseFacade.updateHistoryID(giver_id, geter_id, "insert", table_id, tp_id);
                    }

                    changedAccess.setPrivileges(AccessType.INSERT, true);

                    if (access.getUserGivePermission(AccessType.INSERT)) {
                        changedAccess.setUserGivePermission(AccessType.INSERT, true);
                        givePermission = true;
                    } else {
                        givePermission = changedAccess.getUserGivePermission(AccessType.INSERT);
                    }

                    if (DatabaseFacade.isPermissionsInDatabase(geter_id, table_id, "insert")) {
                        DatabaseFacade.setTablePriveleges(geter_id, table_id, "insert", true, givePermission);
                    } else {
                        DatabaseFacade.insertNewPermission(geter_id, table_id, "insert", true, givePermission);
                    }

                    revokePermission(table_id, "insert", tableName, giver_id);
                }

                //DELETE
                if (access.getPrivilegesStatus(AccessType.DELETE)) {
                    if(changedAccess.getPrivilegesStatus(AccessType.DELETE)== false){
                        //UPDATE histori
                        tp_id = DatabaseFacade.getTablePrivelegesId(geter_id, table_id, "delete");
                        DatabaseFacade.updateHistoryID(giver_id, geter_id, "delete", table_id, tp_id);
                    }
                    changedAccess.setPrivileges(AccessType.DELETE, true);

                    if (access.getUserGivePermission(AccessType.DELETE)) {
                        changedAccess.setUserGivePermission(AccessType.DELETE, true);
                        givePermission = true;
                    } else {
                        givePermission = changedAccess.getUserGivePermission(AccessType.DELETE);
                    }

                    if (DatabaseFacade.isPermissionsInDatabase(geter_id, table_id, "delete")) {
                        DatabaseFacade.setTablePriveleges(geter_id, table_id, "delete", true, givePermission);
                    } else {
                        DatabaseFacade.insertNewPermission(geter_id, table_id, "delete", true, givePermission);
                    }

                    revokePermission(table_id, "delete", tableName, giver_id);
                }

                //UPDATE
                if (access.getPrivilegesStatus(AccessType.UPDATE)) {
                    if(changedAccess.getPrivilegesStatus(AccessType.UPDATE)== false){
                        //UPDATE histori
                        tp_id = DatabaseFacade.getTablePrivelegesId(geter_id, table_id, "update");
                        DatabaseFacade.updateHistoryID(giver_id, geter_id, "update", table_id, tp_id);
                    }

                    changedAccess.setPrivileges(AccessType.UPDATE, true);

                    if (access.getUserGivePermission(AccessType.UPDATE)) {
                        changedAccess.setUserGivePermission(AccessType.UPDATE, true);
                        givePermission = true;
                    } else {
                        givePermission = changedAccess.getUserGivePermission(AccessType.UPDATE);
                    }

                    if (DatabaseFacade.isPermissionsInDatabase(geter_id, table_id, "update")) {
                        DatabaseFacade.setTablePriveleges(geter_id, table_id, "update", true, givePermission);
                    } else {
                        DatabaseFacade.insertNewPermission(geter_id, table_id, "update", true, givePermission);
                    }

                    revokePermission(table_id, "update", tableName, giver_id);
                }

                access.setPrivileges(AccessType.SELECT, false);
                access.setPrivileges(AccessType.INSERT, false);
                access.setPrivileges(AccessType.DELETE, false);
                access.setPrivileges(AccessType.UPDATE, false);

                //Usunięcua histori dla danego użytkownika
                //WERSJA BEZ PZEKAZYWANIA PRAWA DALEJ
                
                historyId = DatabaseFacade.getHistoryIDByUserGet(giver_id, "select",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(giver_id, "insert",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(giver_id, "delete",table_id);
                DatabaseFacade.deleteHistories(historyId);

                historyId = DatabaseFacade.getHistoryIDByUserGet(giver_id, "update",table_id);
                DatabaseFacade.deleteHistories(historyId);
                
                
                //WERSJA Z PRZEKAZYWANIE PRAWA DALEJ
            //    DatabaseFacade.updateHistoryID(giver_id, geter_id);

            }
            dacPanel.refreshPanelsAccess();

        } catch (SQLException ex) {
            Logger.getLogger(UserPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }



    public User getUser() {
        return user;
    }

    public void setUserName(String name) {
        userToggleBtn.setText(name);
    }

    public void setUserName() {
        if (user != null) {
            userToggleBtn.setText(user.getUserName());
        }
    }

    public boolean isButtonSelected() {
        return userToggleBtn.isSelected();
    }

    public void toggleButton() {
        userToggleBtn.doClick();
    }

    public boolean containToggleButton(JToggleButton tButton) {
        if (userToggleBtn == tButton) {
            return true;
        }
        return false;
    }

    public void setAccess(UserAccess userAccess) {
        user.setUserAccess(userAccess);
    }

    public void refreshAccessView() {
         if (user.getUserAccess() == null) {
                user.setUserAccess(new UserAccess());
            }
        if (MainDACFrame.adminMode == true) {
            UserAccess userAccess = user.getUserAccess();
            boolean givePriv = userAccess.getPrivilegesStatus(AccessType.GIVE_PRIV);
            if(givePriv == true){
                userToggleBtn.setSelected(true);
            }
        } else {
        }
    }

    private void revokePermission(int table_id, String permissionName, String tableName, int user_give_id) {
        try {
            System.out.println("Użytkownik " + DatabaseFacade.getUserName(user_give_id) + " zbiera prawa " + permissionName + " do " + tableName);
            int tp_id = DatabaseFacade.getTablePrivelegesId(user_give_id, table_id, permissionName);
            //Pobranie id histori w których rozdaliśmy dane uprawnienie
            ArrayList<Integer> historiesId = DatabaseFacade.getHistoryID(user_give_id, permissionName, table_id);
            //Zabranie użytkownikom uprawnienia
            for (int hisId : historiesId) {
                System.out.println("Szukanie w histori " + hisId);
                int tpIdToRevoke = DatabaseFacade.getTablePermissionIdByHistory(hisId);
                int user_get_id = DatabaseFacade.getHistoryUserGetId(hisId);
                //Zmiana uprawnień w bazie
                DatabaseFacade.removeAllPrivileges(tpIdToRevoke);

                //Zmiana uprawnień lokalnie
                String userGetName = DatabaseFacade.getUserName(user_get_id);
                User userGet = usersManager.getUser(userGetName);
                TableAccess userGetTableAccess = userGet.getTableAccess(tableName);

                if (permissionName.equals("select")) {
                    userGetTableAccess.setPrivileges(AccessType.SELECT, false);
                    userGetTableAccess.setUserGivePermission(AccessType.SELECT, false);
                }

                if (permissionName.equals("insert")) {
                    userGetTableAccess.setPrivileges(AccessType.INSERT, false);
                    userGetTableAccess.setUserGivePermission(AccessType.INSERT, false);
                }

                if (permissionName.equals("update")) {
                    userGetTableAccess.setPrivileges(AccessType.UPDATE, false);
                    userGetTableAccess.setUserGivePermission(AccessType.UPDATE, false);
                }

                if (permissionName.equals("delete")) {
                    userGetTableAccess.setPrivileges(AccessType.DELETE, false);
                    userGetTableAccess.setUserGivePermission(AccessType.DELETE, false);
                }

                revokePermission(table_id, permissionName, tableName, user_get_id);

            }

            //Usunięcie histori
            DatabaseFacade.deleteHistories(historiesId);
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}
